using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Services;
using Sudoku.Menu;
using Sudoku.Lang;
using Sudoku.Utilities;
using System.Diagnostics;

#if !SUDOKU_MASTER
using Microsoft.Advertising.Mobile.Xna;
#endif

namespace Sudoku.GamePlay
{
	public class UIRenderer : ExtendedGameComponent
	{

#if !SUDOKU_MASTER
		AdManager adManager;

		private Texture2D ad_Bg;
		private Rectangle ad_BgRect;
		private Color ad_BgColor;

#endif

		SpriteFont timeFont;
		Vector2 timePos;
		Color timeColor;
		HintButton hintBtn;

		TransitionScreen transition;

		public UIRenderer(Game game)
			: base(game)
		{
			UpdateOrder = (int)ComponentOrders.UI;
			DrawOrder = (int)ComponentOrders.UI;

#if !SUDOKU_MASTER
			adManager = game.Services.GetService(typeof(AdManager)) as AdManager;
#endif
		}

		IBoard boardService;
		
		public override void Initialize()
		{
			boardService = Game.Services.GetService(typeof(IBoard)) as IBoard;
			SpriteFont font = fontService.Font(FontType.Delicious13);

#if !SUDOKU_MASTER
			ad_Bg = textureService.Texture("WhiteFill");
			ad_BgRect = new Rectangle(0, 750, 480, 50);
			ad_BgColor = new Color(0, 0, 0, 255);
			
			// New Game Button
			LabelButton newGameBtn = new LabelButton(Game, new Rectangle(12, 680, 112, 70), LocalizedStrings.ButtonNewGame, font, Color.White, LabelStyle.BOTTOM);
			newGameBtn.OnTap += new Button.ButtonEvent(OnNewGameButton);
			newGameBtn.Texture = textureService.Texture("NewGame");
			if(Guide.IsTrialMode)
			{
				var trial = Game.Services.GetService(typeof(ITrialService)) as ITrialService;
				if (trial.GamesLeft() <= 0) newGameBtn.Enabled = false;
			}
			this.Components.Add(newGameBtn);

			LabelButton resetBtn = new LabelButton(Game, new Rectangle(128, 680, 112, 70), LocalizedStrings.ButtonReset, font, Color.White, LabelStyle.BOTTOM);
			resetBtn.OnTap += new Button.ButtonEvent(OnResetButton);
			resetBtn.Texture = textureService.Texture("Reset");
			this.Components.Add(resetBtn);

			hintBtn = new HintButton(Game, new Rectangle(243, 680, 112, 70), boardService.GetHintLeft(), font, Color.White);
			hintBtn.OnTap += new Button.ButtonEvent(OnHintButton);
			hintBtn.Texture = textureService.Texture("Hint");
			this.Components.Add(hintBtn);

			LabelButton quitBtn = new LabelButton(Game, new Rectangle(358, 680, 112, 70), LocalizedStrings.ButtonQuit, font, Color.White, LabelStyle.BOTTOM);
			quitBtn.OnTap += new Button.ButtonEvent(OnQuitButton);
			quitBtn.Texture = textureService.Texture("Quit");
			this.Components.Add(quitBtn);

			timeFont = fontService.Font(FontType.DeliciousSmallCaps22);
			timePos = new Vector2( 240 - (timeFont.MeasureString(Utils.GetTimeString(0)).X*0.5f) , 654);
			timeColor = new Color(51, 102, 102);
#else
			// New Game Button
			LabelButton newGameBtn = new LabelButton(Game, new Rectangle(12, 710, 112, 83), LocalizedStrings.ButtonNewGame, font, Color.White, LabelStyle.BOTTOM);
			newGameBtn.OnTap += new Button.ButtonEvent(OnNewGameButton);
			newGameBtn.Texture = textureService.Texture("NewGame");
			if(Guide.IsTrialMode)
			{
				var trial = Game.Services.GetService(typeof(ITrialService)) as ITrialService;
				if (trial.GamesLeft() <= 0) newGameBtn.Enabled = false;
			}
			this.Components.Add(newGameBtn);

			LabelButton resetBtn = new LabelButton(Game, new Rectangle(128, 710, 112, 83), LocalizedStrings.ButtonReset, font, Color.White, LabelStyle.BOTTOM);
			resetBtn.OnTap += new Button.ButtonEvent(OnResetButton);
			resetBtn.Texture = textureService.Texture("Reset");
			this.Components.Add(resetBtn);

			hintBtn = new HintButton(Game, new Rectangle(243, 710, 112, 83), boardService.GetHintLeft(), font, Color.White);
			hintBtn.OnTap += new Button.ButtonEvent(OnHintButton);
			hintBtn.Texture = textureService.Texture("Hint");
			this.Components.Add(hintBtn);

			LabelButton quitBtn = new LabelButton(Game, new Rectangle(358, 710, 112, 83), LocalizedStrings.ButtonQuit, font, Color.White, LabelStyle.BOTTOM);
			quitBtn.OnTap += new Button.ButtonEvent(OnQuitButton);
			quitBtn.Texture = textureService.Texture("Quit");
			this.Components.Add(quitBtn);

			timeFont = fontService.Font(FontType.DeliciousSmallCaps22);
			timePos = new Vector2( 240 - (timeFont.MeasureString(Utils.GetTimeString(0)).X*0.5f) , 670);
			timeColor = new Color(51, 102, 102);
#endif
			if (Guide.IsTrialMode)
			{
				var trial = Game.Services.GetService(typeof(ITrialService)) as ITrialService;
				String s;
				short i = trial.GamesLeft();
				s = (i <= 0) ?  
					LocalizedStrings.TrialNoGames :
					String.Format(LocalizedStrings.TrialNGames, i);
				float x = 240 - (timeFont.MeasureString(s).X * 0.5f);
				BlinkString bs = new BlinkString(Game, timeFont, s, new Vector2(x, 0), Color.Red, 5000, 1000);
				this.Components.Add(bs);
			}

			transition = null;

			var inputService = Game.Services.GetService(typeof(IInputManager)) as IInputManager;
			inputService.OnBack += new InputManager.PhoneButtonEvent(Back);

			base.Initialize();
		}


#if !SUDOKU_MASTER
		protected override void LoadContent()
		{

			adManager.CreateAd("36002", new Rectangle(0, 750, 480, 50), RotationMode.Automatic);

			base.LoadContent();
		}

		protected override void UnloadContent()
		{
			adManager.RemoveAll();

			base.UnloadContent();
		}
#endif

		#region BUTTONS

		private void TransitionEnd()
		{
			transition.OnTransitionEnd -= new Action(TransitionEnd);
			Game.Components.Remove(transition); 
			transition.Dispose();
			transition = null;
		}

		private void StartTransition()
		{
			transition = new TransitionScreen(Game);
			transition.OnTransitionEnd += new Action(TransitionEnd);
			Game.Components.Add(transition);
		}

		private void OnNewGameButton(Button sender)
		{
			//should we save?
			NotifyScreen notify = new NotifyScreen(Game, 
													LocalizedStrings.NewBoxTitle,
													LocalizedStrings.NewBoxText, 
													LocalizedStrings.NewBoxYes,
													LocalizedStrings.NewBoxNo);

			notify.OnResponse += new NotifyScreen.NotifyEvent(OnNewGameResponse);

		}

		private void OnNewGameResponse(bool value)
		{
			StartTransition();
			if (value) StateManagement.StateManager.StartLevel(Game, boardService.GetScore().Difficulty);
		}

		private void OnResetButton(Button sender)
		{
			//should we save?
			NotifyScreen notify = new NotifyScreen(Game,
													LocalizedStrings.ResetBoxTitle,
													LocalizedStrings.ResetBoxText,
													LocalizedStrings.ResetBoxYes,
													LocalizedStrings.ResetBoxNo);

			notify.OnResponse += new NotifyScreen.NotifyEvent(OnResetResponse);
		}

		private void OnResetResponse(bool value)
		{
			StartTransition();
			
			if (value)
			{
				boardService.Reset();
				hintBtn.HintsLeft = boardService.GetHintLeft();
				hintBtn.Enabled = true;
			}
		}

		private void OnHintButton(Button sender)
		{
			boardService.GetHint();
			hintBtn.HintsLeft = boardService.GetHintLeft();
			hintBtn.Enabled = hintBtn.HintsLeft != 0;
		}

		private void Back()
		{
			if (!this.Enabled) return;

			Quit();
		}

		private void OnQuitButton(Button sender)
		{
			Quit();
		}

		private void Quit()
		{
			//should we save?
			String s = LocalizedStrings.QuitBoxText;

#if !SUDOKU_MASTER
			s = s.Substring(s.IndexOf('.') + 2);
#endif
			NotifyScreen notify = new NotifyScreen(Game,
													LocalizedStrings.QuitBoxTitle,
													s,
													LocalizedStrings.QuitBoxYes,
													LocalizedStrings.QuitBoxNo);

			notify.OnResponse += new NotifyScreen.NotifyEvent(OnQuitResponse);
		}

		private void OnQuitResponse(bool value)
		{
			if (value)
			{
				// Save the game before quitting
				ISaveService saveService = (ISaveService)Game.Services.GetService(typeof(ISaveService));
				saveService.SaveGame();
				soundService.PlaySound(SoundType.Fumble);

				StateManagement.StateManager.StartMenu(Game);
			}
			else StartTransition();
			
		}

		#endregion

		public override void Draw(GameTime gameTime)
		{
			spriteBatch.Begin();
			
			#if !SUDOKU_MASTER
			spriteBatch.Draw(ad_Bg, ad_BgRect, ad_BgColor);
			#endif
			
			spriteBatch.DrawString( timeFont, Utils.GetTimeString(boardService.GetTime()), timePos, timeColor); 

			spriteBatch.End();

			base.Draw(gameTime);
		}
	}
}
